﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using FCDB.Entity;
using FCDB.Entity.EntityEx;
 

namespace FCDB.Repository
{
    public class WfProcessInstanceRepository : LogicBase, ILogic
    {
        private RegularMeetingRepository Regularrespository = new RegularMeetingRepository();
        
        public static IQueryable<FCDB.Entity.EntityEx.WfActivityInstanceTasksEx> GetActivityInstanceTasks()
        {
            var query = from item in DBHelper.WfActivityInstance
                        join task in DBHelper.WfTasks on item.ID equals task.ActivityInstanceID
                        join processInstance in DBHelper.WfProcessInstance on item.ProcessInstanceID equals processInstance.ID
                        select new  WfActivityInstanceTasksEx()
                        {
                            ActivityGUID = item.ActivityGUID,
                            ActivityInstanceID = task.ActivityInstanceID,
                            ActivityName = task.ActivityName,
                            ActivityState = item.State,
                            ActivityType = item.ActivityType,
                            AppInstanceID = item.AppInstanceID,
                            AppName = item.AppName,
                            AssignedToUserID = task.AssignedToUserID,
                            AssignedToUserName = task.AssignedToUserName,
                            CreatedByUserID = task.CreatedByUserID,
                            CreatedByUserName = task.CreatedByUserName,
                            CreatedDateTime = task.CreatedDateTime,
                            EndedByUserID = task.EndedByUserID,
                            EndedByUserName = task.EndedByUserName,
                            EndedDateTime = task.EndedDateTime,
                            IsActivityCompleted = item.IsActivityCompleted,
                            ProcessGUID = item.ProcessGUID,
                            ProcessInstanceID = item.ProcessInstanceID,
                            ProcessState = processInstance.ProcessState,
                            TaskID = task.ID,
                            TaskState = task.TaskState,
                            TaskType = task.TaskType,
                            RecordStatusInvalid = task.RecordStatusInvalid,
                            ReadyTaskType = 1,
                            SendUserID = Guid.NewGuid(),

                            // 测试为了判断是否是撤回而建立
                            State = item.State
                        };
            return query;
        }

        public IList<WfProcessInstance> GetProcessInstance(string appName, long appInstanceID, Guid processGUID)
        {
            var query = from item in DBHelper.WfProcessInstance
                        where item.AppInstanceID == appInstanceID && item.ProcessGUID == processGUID && item.RecordStatusInvalid == 0
                        orderby item.CreatedDateTime descending
                        select item;
            return query.ToList();
        }

        public bool DeleteProcessInstance(long appInstanceID)
        {
            try
            {

                WfProcessInstance wfProcessInstance = Get<WfProcessInstance>(appInstanceID);
                IList<WfTransitionInstance> wfInstanceList = DBHelper.WfTransitionInstance.Where(t => t.AppInstanceID == appInstanceID).ToList();
                foreach (var item in wfInstanceList)
                {
                    DeleteByNoSave(item);
                }
                IList<WfActivityInstance> wfActivityInstanceList = DBHelper.WfActivityInstance.Where(t => t.AppInstanceID == appInstanceID).ToList();
                foreach (var item in wfActivityInstanceList)
                {
                    DeleteByNoSave(item);
                }
                IList<WfTasks> wfWfTasksList = DBHelper.WfTasks.Where(t => t.AppInstanceID == appInstanceID).ToList();
                foreach (var item in wfActivityInstanceList)
                {
                    DeleteByNoSave(item);
                }

                DeleteByNoSave(wfProcessInstance);
                SaveChagnes();
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

        public bool Discard(string appName, long appInstanceID, Guid processGUID, Guid userID, string userName)
        {
            var isDiscarded = false;

            var query = from item in DBHelper.WfProcessInstance
                        where item.AppInstanceID == appInstanceID && item.ProcessGUID == processGUID && item.ProcessState != 32
                        select item;
            bool flag = query.Count() > 0;
            foreach (var item in query)
            {
                item.ProcessState = 32;
                item.RecordStatusInvalid = 1;
                item.LastUpdatedDateTime = DateTime.Now;
                item.LastUpdatedByUserID = userID;
                item.LastUpdatedByUserName = userName;
                UpdateByNoSave(item);
            }
            if (query.Count() > 0)
            {
                isDiscarded = SaveChagnes() > 0;
            }
            return isDiscarded;
        }


        /// <summary>
        /// 获取用户发起的流程
        /// </summary>
        /// <param name="userID">用户ID</param>
        /// <param name="skip"></param>
        /// <param name="take"></param>
        /// <param name="total"></param>
        /// <param name="dtStart"></param>
        /// <param name="dtEnd"></param>
        /// <param name="kewyword"></param>
        /// <param name="ProcessGuid"></param>
        /// <returns></returns>
        public IList<WfProcessInstanceEx> GetMyProcessInstance(Guid userID, int skip, int take,
            out int total, string dtStart = "", string dtEnd = "", string kewyword = "", string ProcessGuid = "")
        {
            var transtion = WfActivityInstanceTasksRepository.GetActivityInstanceTasks();
            var query = from item in DBHelper.WfProcessInstance
                        where item.CreatedByUserID == userID
                        select item;
            if (!string.IsNullOrEmpty(dtStart) && !string.IsNullOrEmpty(dtEnd))
            {
                DateTime dtStartTime = DateTime.Parse(dtStart);
                DateTime dtEndTime = DateTime.Parse(dtEnd);
                query = query.Where(t => t.CreatedDateTime >= dtStartTime && t.CreatedDateTime < dtEndTime);
            }
            if (!string.IsNullOrEmpty(ProcessGuid))
            {
                query = query.Where(t => t.ProcessGUID == new Guid(ProcessGuid));
            }
            if (!string.IsNullOrEmpty(kewyword))
            {
                long instanceID = 0;
                long.TryParse(kewyword, out instanceID);
                if (instanceID == 0)
                {
                    query = query.Where(t => t.AppName.IndexOf(kewyword) > -1);
                }
                else
                {
                    query = query.Where(t => t.AppInstanceID == instanceID);
                }
            }
            total = query.Distinct().Count();
            IList<WfProcessInstance> WfProcessInstanceList = query.Distinct().OrderByDescending(t => t.CreatedDateTime).Skip(skip).Take(take).ToList();
            IList<WfProcessInstanceEx> WfProcessInstanceExList = new List<WfProcessInstanceEx>();
            foreach (WfProcessInstance item in WfProcessInstanceList)
            {
                WfProcessInstanceEx model = new WfProcessInstanceEx()
                {
                    RowVersionID = item.RowVersionID,
                    AppInstanceCode = item.AppInstanceCode,
                    AppInstanceID = item.AppInstanceID,
                    AppName = item.AppName,
                    CreatedByUserID = item.CreatedByUserID,
                    CreatedDateTime = item.CreatedDateTime,
                    EndedByUserID = item.EndedByUserID,
                    EndedByUserName = item.EndedByUserName,
                    ID = item.ID,
                    CreatedByUserName = item.CreatedByUserName,
                    EndedDateTime = item.EndedDateTime,
                    IsProcessCompleted = item.IsProcessCompleted,
                    LastUpdatedByUserID = item.LastUpdatedByUserID,
                    LastUpdatedByUserName = item.LastUpdatedByUserName,
                    LastUpdatedDateTime = item.LastUpdatedDateTime,
                    ProcessGUID = item.ProcessGUID,
                    ProcessName = item.ProcessName,
                    ProcessState = item.ProcessState,
                    RecordStatusInvalid = item.RecordStatusInvalid,
                    IsCanDelete = true
                };
                bool isCanDelete = true;
                IList<WfActivityInstanceTasksEx> list = transtion.Where(t => t.AppInstanceID == model.AppInstanceID).OrderByDescending(t => t.CreatedDateTime).ToList();
                foreach (var taskItem in list)
                {
                    if ((taskItem.EndedByUserID.HasValue && taskItem.EndedByUserID != model.CreatedByUserID) ||
                        (taskItem.LastUpdatedByUserID.HasValue && taskItem.LastUpdatedByUserID != model.CreatedByUserID))
                    {
                        isCanDelete = false;
                        break;
                    }
                }
                model.IsCanDelete = isCanDelete;
                WfActivityInstanceTasksEx taskEx = list.First();
                model.ActivityName = taskEx.ActivityName;
                model.SendUserName = taskEx.CreatedByUserName;
                if (item.ProcessState == 2)
                {
                    model.ReceiveUserName = "";
                    StringBuilder strBuilder = new StringBuilder();
                    list = list.Where(t => t.TaskState < 4).ToList();
                    foreach (var taskItemEx in list)
                    {
                        strBuilder.Append(taskItemEx.AssignedToUserName + ",");
                    }
                    if (strBuilder.Length > 0)
                    {
                        model.ReceiveUserName = strBuilder.ToString(0, strBuilder.Length - 1);
                    }
                }
                WfProcessInstanceExList.Add(model);
            }

            return WfProcessInstanceExList;
        }

        public IList<WfProcessInstanceEx> GetAllProccessInstance(Guid userId, short state, int skip, int take, int? ProcessStatus, out int total, string ky = "", long typeID = 0, string dtStart = "", string dtEnd = "",
         string kewyword = "", string UserIDs = "", string DeparmentID = "", string ProcessGuid = "")
        {
            var efemployeeInfoProvider = FB.Providers.AspNetEmployeeInfoProviderManager.Default as FB.Providers.EFEmployeeInfoProvider;
            FB.Providers.EmployeeInfo.EmployeeInfoUnit unitinfo = efemployeeInfoProvider.GetEmployeeInfoUnit();
            var transtion = WfActivityInstanceTasksRepository.GetActivityInstanceTasks();
            var query = (from item in DBHelper.WfProcessInstance
                         join log in DBHelper.FormCirculatedDocumentLog on item.AppInstanceID equals log.AppInstanceID into docLog
                         from FormDocLog in docLog.DefaultIfEmpty()
                         join trans in transtion on item.AppInstanceID equals trans.AppInstanceID
                         where item.CreatedByUserID == userId || trans.CreatedByUserID == userId || trans.AssignedToUserID == userId
                         || item.EndedByUserID == userId || item.LastUpdatedByUserID == userId || trans.EndedByUserID == userId
                         || FormDocLog.UserID == userId
                         select new WfProcessInstanceEx()
                         {
                             AppInstanceCode = item.AppInstanceCode,
                             AppInstanceID = item.AppInstanceID,
                             AppName = item.AppName,
                             CreatedByUserID = item.CreatedByUserID,
                             CreatedByUserName = item.CreatedByUserName,
                             CreatedDateTime = item.CreatedDateTime,
                             EndedByUserID = item.EndedByUserID,
                             EndedByUserName = item.EndedByUserName,
                             EndedDateTime = item.EndedDateTime,
                             ID = item.ID,
                             IsProcessCompleted = item.IsProcessCompleted,
                             LastUpdatedByUserID = item.LastUpdatedByUserID,
                             LastUpdatedByUserName = item.LastUpdatedByUserName,
                             LastUpdatedDateTime = item.LastUpdatedDateTime,
                             ProcessGUID = item.ProcessGUID,
                             RecordStatusInvalid = item.RecordStatusInvalid,
                             ProcessState = item.ProcessState,
                             ProcessName = item.ProcessName,
                             RowVersionID = item.RowVersionID,
                             CheckType = FormDocLog != null ? FormDocLog.CheckType.Value + 1 : 1,

                         }).Distinct();
            if (state > 0)
            {
                query = query.Where(t => t.ProcessState == state);
            }
            if (ProcessStatus>0)
            {
                if (ProcessStatus.Value == 1)
                {
                    query =  from item in query 
                            where item.ProcessState < 4
                            select item;
                }
                else
                {
                    query = from item in query
                            where item.ProcessState >= 4
                            select item;
                  
                } 
            }
            if (typeID > 0)
            {
                query = from item in query
                        join process in DBHelper.WfProcess on item.ProcessGUID equals process.ProcessGUID
                        where process.WfProcessTypeID == typeID
                        select item;
            }
            if (!string.IsNullOrEmpty(dtStart) && !string.IsNullOrEmpty(dtEnd))
            {
                DateTime dtStartTime = DateTime.Parse(dtStart);
                DateTime dtEndTime = DateTime.Parse(dtEnd);
                query = query.Where(t => t.CreatedDateTime >= dtStartTime && t.CreatedDateTime <= dtEndTime);
            }
            if (!string.IsNullOrEmpty(DeparmentID))
            {
                IList<vw_Employees> employee = Regularrespository.GetEmployeeByDeparment(DeparmentID);
                foreach (var i in employee)
                {
                    UserIDs = UserIDs + ";" + i.UserID.ToString();
                }
            }
            if (!string.IsNullOrEmpty(ProcessGuid))
            {
                query = query.Where(t => t.ProcessGUID == new Guid(ProcessGuid));
            }
            if (!string.IsNullOrEmpty(UserIDs))
            {
                List<Guid?> UserIDList = new List<Guid?>();
                string[] strUserID = UserIDs.Split(";".ToArray());
                foreach (string item in strUserID)
                {
                    if (!string.IsNullOrEmpty(item))
                    {
                        UserIDList.Add(new Guid(item));
                    }
                }
                query = query.Where(t => UserIDList.Contains(t.CreatedByUserID));
            }

            if (!string.IsNullOrEmpty(kewyword))
            {
                long instanceID = 0;
                long.TryParse(kewyword, out instanceID);
                if (instanceID == 0)
                {
                    query = query.Where(t => t.AppName.IndexOf(kewyword) > -1);
                }
                else
                {
                    query = query.Where(t => t.AppInstanceID == instanceID);
                }

            }
            if (!string.IsNullOrEmpty(ky))
            {
                long instanceID = 0;
                long.TryParse(ky, out instanceID);
                if (instanceID == 0)
                {
                    query = query.Where(t => t.AppName.IndexOf(ky) > -1);
                }
                else
                {
                    query = query.Where(t => t.AppInstanceID == instanceID);
                }

            }
            total = query.Count();
            IList<WfProcessInstanceEx> WfProcessInstanceList = query.OrderByDescending(t => t.LastUpdatedDateTime).Skip(skip).Take(take).ToList();

            foreach (WfProcessInstanceEx item in WfProcessInstanceList)
            {
                if (item.CheckType == 2)
                {
                    item.AppName = "传阅：" + item.AppName;
                }
                if (item.CheckType == 3)
                {
                    item.AppName = "征求意见：" + item.AppName;
                }
                IList<WfActivityInstanceTasksEx> list = transtion.Where(t => t.AppInstanceID == item.AppInstanceID).OrderByDescending(t => t.CreatedDateTime).ToList();

                WfActivityInstanceTasksEx taskEx = list.First();
                item.ActivityName = taskEx.ActivityName;
                item.SendUserName = taskEx.CreatedByUserName;
                if (item.ProcessState == 2)
                {
                    item.ReceiveUserName = "";
                    StringBuilder strBuilder = new StringBuilder();
                    list = list.Where(t => t.TaskState < 4 && (t.ActivityState == 1 || t.ActivityState == 2)).ToList();
                    foreach (var taskItemEx in list)
                    {
                        strBuilder.Append(taskItemEx.AssignedToUserName + ",");
                    }
                    if (strBuilder.Length > 0)
                    {
                        item.ReceiveUserName = strBuilder.ToString(0, strBuilder.Length - 1);
                    }
                }

                if (item.ProcessGUID.ToString().Equals("0e37f0c1-737b-4653-93dd-d01a3fbc28f7"))
                {
                    FormRepository repository = new FormRepository();
                    FormCDB fcdb = repository.GetForm<FormCDB>(item.AppInstanceID);
                    if (fcdb.financiaAmount == null || fcdb.financiaAmount == 0)
                    {
                        item.isRed = "【未收款】";
                    }
                    else
                    {
                        item.isRed = "";
                    }
                }
                else
                {
                    item.isRed = "";
                }
            }

            return WfProcessInstanceList;
        }
        public IList<WfProcessInstanceEx> GetAllProccessInstance(Guid userId, short state, int skip, int take, out int total, string ky = "", long typeID = 0, string dtStart = "", string dtEnd = "",
         string kewyword = "", string UserIDs = "", string DeparmentID = "", string ProcessGuid = "")
        {
            var efemployeeInfoProvider = FB.Providers.AspNetEmployeeInfoProviderManager.Default as FB.Providers.EFEmployeeInfoProvider;
            FB.Providers.EmployeeInfo.EmployeeInfoUnit unitinfo = efemployeeInfoProvider.GetEmployeeInfoUnit();
            var transtion = WfActivityInstanceTasksRepository.GetActivityInstanceTasks();
            var query = (from item in DBHelper.WfProcessInstance
                         join log in DBHelper.FormCirculatedDocumentLog on item.AppInstanceID equals log.AppInstanceID into docLog
                         from FormDocLog in docLog.DefaultIfEmpty()
                         join trans in transtion on item.AppInstanceID equals trans.AppInstanceID
                         where item.CreatedByUserID == userId || trans.CreatedByUserID == userId || trans.AssignedToUserID == userId
                         || item.EndedByUserID == userId || item.LastUpdatedByUserID == userId || trans.EndedByUserID == userId
                         || FormDocLog.UserID == userId
                         select new WfProcessInstanceEx()
                         {
                             AppInstanceCode = item.AppInstanceCode,
                             AppInstanceID = item.AppInstanceID,
                             AppName = item.AppName,
                             CreatedByUserID = item.CreatedByUserID,
                             CreatedByUserName = item.CreatedByUserName,
                             CreatedDateTime = item.CreatedDateTime,
                             EndedByUserID = item.EndedByUserID,
                             EndedByUserName = item.EndedByUserName,
                             EndedDateTime = item.EndedDateTime,
                             ID = item.ID,
                             IsProcessCompleted = item.IsProcessCompleted,
                             LastUpdatedByUserID = item.LastUpdatedByUserID,
                             LastUpdatedByUserName = item.LastUpdatedByUserName,
                             LastUpdatedDateTime = item.LastUpdatedDateTime,
                             ProcessGUID = item.ProcessGUID,
                             RecordStatusInvalid = item.RecordStatusInvalid,
                             ProcessState = item.ProcessState,
                             ProcessName = item.ProcessName,
                             RowVersionID = item.RowVersionID,
                             CheckType = FormDocLog != null ? FormDocLog.CheckType.Value + 1 : 1,

                         }).Distinct();
            if (state > 0)
            {
                query = query.Where(t => t.ProcessState == state);
            }

            if (typeID > 0)
            {
                query = from item in query
                        join process in DBHelper.WfProcess on item.ProcessGUID equals process.ProcessGUID
                        where process.WfProcessTypeID == typeID
                        select item;
            }
            if (!string.IsNullOrEmpty(dtStart) && !string.IsNullOrEmpty(dtEnd))
            {
                DateTime dtStartTime = DateTime.Parse(dtStart);
                DateTime dtEndTime = DateTime.Parse(dtEnd);
                query = query.Where(t => t.CreatedDateTime >= dtStartTime && t.CreatedDateTime <= dtEndTime);
            }
            if (!string.IsNullOrEmpty(DeparmentID))
            {
                IList<vw_Employees> employee = Regularrespository.GetEmployeeByDeparment(DeparmentID);
                foreach (var i in employee)
                {
                    UserIDs = UserIDs + ";" + i.UserID.ToString();
                }
            }
            if (!string.IsNullOrEmpty(ProcessGuid))
            {
                query = query.Where(t => t.ProcessGUID == new Guid(ProcessGuid));
            }
            if (!string.IsNullOrEmpty(UserIDs))
            {
                List<Guid?> UserIDList = new List<Guid?>();
                string[] strUserID = UserIDs.Split(";".ToArray());
                foreach (string item in strUserID)
                {
                    if (!string.IsNullOrEmpty(item))
                    {
                        UserIDList.Add(new Guid(item));
                    }
                }
                query = query.Where(t => UserIDList.Contains(t.CreatedByUserID));
            }

            if (!string.IsNullOrEmpty(kewyword))
            {
                long instanceID = 0;
                long.TryParse(kewyword, out instanceID);
                if (instanceID == 0)
                {
                    query = query.Where(t => t.AppName.IndexOf(kewyword) > -1);
                }
                else
                {
                    query = query.Where(t => t.AppInstanceID == instanceID);
                }

            }
            if (!string.IsNullOrEmpty(ky))
            {
                long instanceID = 0;
                long.TryParse(ky, out instanceID);
                if (instanceID == 0)
                {
                    query = query.Where(t => t.AppName.IndexOf(ky) > -1);
                }
                else
                {
                    query = query.Where(t => t.AppInstanceID == instanceID);
                }

            }
            total = query.Count();
            IList<WfProcessInstanceEx> WfProcessInstanceList = query.OrderByDescending(t => t.LastUpdatedDateTime).Skip(skip).Take(take).ToList();

            foreach (WfProcessInstanceEx item in WfProcessInstanceList)
            {
                if (item.CheckType == 2)
                {
                    item.AppName = "传阅：" + item.AppName;
                }
                if (item.CheckType == 3)
                {
                    item.AppName = "征求意见：" + item.AppName;
                }
                IList<WfActivityInstanceTasksEx> list = transtion.Where(t => t.AppInstanceID == item.AppInstanceID).OrderByDescending(t => t.CreatedDateTime).ToList();

                WfActivityInstanceTasksEx taskEx = list.First();
                item.ActivityName = taskEx.ActivityName;
                item.SendUserName = taskEx.CreatedByUserName;
                if (item.ProcessState == 2)
                {
                    item.ReceiveUserName = "";
                    StringBuilder strBuilder = new StringBuilder();
                    list = list.Where(t => t.TaskState < 4 && (t.ActivityState == 1 || t.ActivityState == 2)).ToList();
                    foreach (var taskItemEx in list)
                    {
                        strBuilder.Append(taskItemEx.AssignedToUserName + ",");
                    }
                    if (strBuilder.Length > 0)
                    {
                        item.ReceiveUserName = strBuilder.ToString(0, strBuilder.Length - 1);
                    }
                }

                if (item.ProcessGUID.ToString().Equals("0e37f0c1-737b-4653-93dd-d01a3fbc28f7"))
                {
                    FormRepository repository = new FormRepository();
                    FormCDB fcdb = repository.GetForm<FormCDB>(item.AppInstanceID);
                    if (fcdb.financiaAmount == null || fcdb.financiaAmount == 0)
                    {
                        item.isRed = "【未收款】";
                    }
                    else
                    {
                        item.isRed = "";
                    }
                }
                else
                {
                    item.isRed = "";
                }
            }

            return WfProcessInstanceList;
        }

        public IList< WfActivityInstanceTasksEx> GetAllFinaceProccessInstance(Guid userID, short state, int skip, int take, IList<Guid> ProcessGuidList, out int total, string ky = "", long typeID = 0, string dtStart = "", string dtEnd = "",
         string kewyword = "", string UserIDs = "", string DeparmentID = "", string Split = "", String ProcessGuid = "")
        {
            DateTime StartTime = new DateTime(2014, 1, 1);
            var efemployeeInfoProvider = FB.Providers.AspNetEmployeeInfoProviderManager.Default as FB.Providers.EFEmployeeInfoProvider;
            FB.Providers.EmployeeInfo.EmployeeInfoUnit unitinfo = efemployeeInfoProvider.GetEmployeeInfoUnit();
            var queryTasks = GetActivityInstanceTasks();

            var query = from item in queryTasks
                        where item.AssignedToUserID == userID
                        && item.ActivityName.IndexOf("会计") > -1
                        && item.ActivityType == 4 && item.ActivityState == 4
                        && (item.CreatedDateTime >= StartTime)
                        select item;
            var query1 = from item in queryTasks
                         group item by item.AppInstanceID into gitem
                         select new { gitem.Key, TaskID = gitem.Max(mm => mm.TaskID) };
            queryTasks = from item in queryTasks
                         from kk in query1
                         where item.AppInstanceID == kk.Key && item.TaskID == kk.TaskID
                         select item;

            if (!string.IsNullOrEmpty(dtStart) && !string.IsNullOrEmpty(dtEnd))
            {
                DateTime dtStartTime = DateTime.Parse(dtStart);
                DateTime dtEndTime = DateTime.Parse(dtEnd);
                query = query.Where(t => t.CreatedDateTime >= dtStartTime && t.CreatedDateTime <= dtEndTime);
            }
            if (!string.IsNullOrEmpty(kewyword))
            {
                long appInstanceId = 0;
                long.TryParse(kewyword, out appInstanceId);
                if (appInstanceId > 0)
                {
                    query = query.Where(t => t.AppInstanceID == appInstanceId);
                }
                else
                {
                    query = query.Where(t => t.AppName.IndexOf(kewyword) > -1);
                }
            }
            query = query.Where(t => ProcessGuidList.Contains(t.ProcessGUID));
            if (!string.IsNullOrEmpty(ProcessGuid))
            {
                query = query.Where(t => t.ProcessGUID == new Guid(ProcessGuid));
            }
            if (!string.IsNullOrEmpty(DeparmentID))
            {
                IList<vw_Employees> employee = Regularrespository.GetEmployeeByDeparment(DeparmentID);
                foreach (var i in employee)
                {
                    UserIDs = UserIDs + ";" + i.UserID.ToString();
                }
            }
            if (!string.IsNullOrEmpty(UserIDs))
            {
                List<Guid?> UserIDList = new List<Guid?>();
                string[] strUserID = UserIDs.Split(";".ToArray());
                foreach (string item in strUserID)
                {
                    if (!string.IsNullOrEmpty(item))
                    {
                        UserIDList.Add(new Guid(item));
                    }
                }
                query = query.Where(t => UserIDList.Contains(t.CreatedByUserID));
            }

            total = query.Count();
            IList<WfActivityInstanceTasksEx> list = query.OrderByDescending(t => t.CreatedDateTime).Skip(skip).Take(take).ToList();
            return list;
        }

        public IList<WfProcessInstanceEx> GetAllcxlProccessInstance(Guid userId, short state, int skip, int take, out int total, string ky = "", long typeID = 0, string dtStart = "", string dtEnd = "",
         string kewyword = "", string UserIDs = "", string DeparmentID = "", string Split = "")
        {
            DateTime StartTime = new DateTime(2014, 2, 1);
            var efemployeeInfoProvider = FB.Providers.AspNetEmployeeInfoProviderManager.Default as FB.Providers.EFEmployeeInfoProvider;
            FB.Providers.EmployeeInfo.EmployeeInfoUnit unitinfo = efemployeeInfoProvider.GetEmployeeInfoUnit();
            var transtion = WfActivityInstanceTasksRepository.GetActivityInstanceTasks();
            var query = (from item in DBHelper.WfProcessInstance
                         join log in DBHelper.FormCirculatedDocumentLog on item.AppInstanceID equals log.AppInstanceID into docLog
                         from FormDocLog in docLog.DefaultIfEmpty()
                         join trans in transtion on item.AppInstanceID equals trans.AppInstanceID
                         where (item.CreatedByUserID == userId || trans.CreatedByUserID == userId || trans.AssignedToUserID == userId
                         || item.EndedByUserID == userId || item.LastUpdatedByUserID == userId || trans.EndedByUserID == userId
                         || FormDocLog.UserID == userId) && (item.ProcessName == "加班审批表" || item.ProcessName == "考勤异常审批单" || item.ProcessName == "请假审批表")
                         where (item.CreatedDateTime >= StartTime)
                         select new WfProcessInstanceEx()
                         {
                             AppInstanceCode = item.AppInstanceCode,
                             AppInstanceID = item.AppInstanceID,
                             AppName = item.AppName,
                             CreatedByUserID = item.CreatedByUserID,
                             CreatedByUserName = item.CreatedByUserName,
                             CreatedDateTime = item.CreatedDateTime,
                             EndedByUserID = item.EndedByUserID,
                             EndedByUserName = item.EndedByUserName,
                             EndedDateTime = item.EndedDateTime,
                             ID = item.ID,
                             IsProcessCompleted = item.IsProcessCompleted,
                             LastUpdatedByUserID = item.LastUpdatedByUserID,
                             LastUpdatedByUserName = item.LastUpdatedByUserName,
                             LastUpdatedDateTime = item.LastUpdatedDateTime,
                             ProcessGUID = item.ProcessGUID,
                             RecordStatusInvalid = item.RecordStatusInvalid,
                             ProcessState = item.ProcessState,
                             ProcessName = item.ProcessName,
                             RowVersionID = item.RowVersionID,
                             CheckType = FormDocLog != null ? FormDocLog.CheckType.Value + 1 : 1,

                         }).Distinct();
            if (state > 0)
            {
                query = query.Where(t => t.ProcessState == state);
            }

            if (typeID > 0)
            {
                query = from item in query
                        join process in DBHelper.WfProcess on item.ProcessGUID equals process.ProcessGUID
                        where process.WfProcessTypeID == typeID
                        select item;
            }
            if (!string.IsNullOrEmpty(dtStart) && !string.IsNullOrEmpty(dtEnd))
            {
                DateTime dtStartTime = DateTime.Parse(dtStart);
                DateTime dtEndTime = DateTime.Parse(dtEnd);
                query = query.Where(t => t.CreatedDateTime >= dtStartTime && t.CreatedDateTime <= dtEndTime);
            }
            if (!string.IsNullOrEmpty(DeparmentID))
            {
                IList<vw_Employees> employee = Regularrespository.GetEmployeeByDeparment(DeparmentID);
                foreach (var i in employee)
                {
                    UserIDs = UserIDs + ";" + i.UserID.ToString();
                }
            }
            if (!string.IsNullOrEmpty(UserIDs))
            {
                List<Guid?> UserIDList = new List<Guid?>();
                string[] strUserID = UserIDs.Split(";".ToArray());
                foreach (string item in strUserID)
                {
                    if (!string.IsNullOrEmpty(item))
                    {
                        UserIDList.Add(new Guid(item));
                    }
                }
                query = query.Where(t => UserIDList.Contains(t.CreatedByUserID));
            }

            if (!string.IsNullOrEmpty(kewyword))
            {
                long instanceID = 0;
                long.TryParse(kewyword, out instanceID);
                if (instanceID == 0)
                {
                    query = query.Where(t => t.AppName.IndexOf(kewyword) > -1);
                }
                else
                {
                    query = query.Where(t => t.AppInstanceID == instanceID);
                }

            }
            if (!string.IsNullOrEmpty(ky))
            {
                long instanceID = 0;
                long.TryParse(ky, out instanceID);
                if (instanceID == 0)
                {
                    query = query.Where(t => t.AppName.IndexOf(ky) > -1);
                }
                else
                {
                    query = query.Where(t => t.AppInstanceID == instanceID);
                }

            }
            total = query.Count();
            IList<WfProcessInstanceEx> WfProcessInstanceList = query.OrderByDescending(t => t.LastUpdatedDateTime).ToList();

            foreach (WfProcessInstanceEx item in WfProcessInstanceList)
            {
                if (item.CheckType == 2)
                {
                    item.AppName = "传阅：" + item.AppName;
                }
                if (item.CheckType == 3)
                {
                    item.AppName = "征求意见：" + item.AppName;
                }
                IList<WfActivityInstanceTasksEx> list = transtion.Where(t => t.AppInstanceID == item.AppInstanceID).OrderByDescending(t => t.CreatedDateTime).ToList();

                WfActivityInstanceTasksEx taskEx = list.First();
                item.ActivityName = taskEx.ActivityName;
                item.SendUserName = taskEx.CreatedByUserName;
                if (item.ProcessState == 2)
                {
                    item.ReceiveUserName = "";
                    StringBuilder strBuilder = new StringBuilder();
                    list = list.Where(t => t.TaskState < 4 && (t.ActivityState == 1 || t.ActivityState == 2)).ToList();
                    foreach (var taskItemEx in list)
                    {
                        strBuilder.Append(taskItemEx.AssignedToUserName + ",");
                    }
                    if (strBuilder.Length > 0)
                    {
                        item.ReceiveUserName = strBuilder.ToString(0, strBuilder.Length - 1);
                    }
                }
            }

            return WfProcessInstanceList;
        }

        public IList<Guid?> GetDepartmentUser(Guid UserID)
        {
            vw_Employees employee = DBHelper.vw_Employees.First(t => t.UserID == UserID);
            IList<String> EmployeeInPositions = DBHelper.vw_EmployeeInPositions.Where(t => t.EMPCode == employee.EMPCode).Select(t => t.DEPTCode).ToList();
            var query = from item in DBHelper.vw_Employees
                        join position in DBHelper.vw_EmployeeInPositions on item.EMPCode equals position.EMPCode
                        where EmployeeInPositions.Contains(position.DEPTCode)
                        select item.UserID;
            return query.Distinct().ToList();
        }

        #region 2013-10-8扩展
        public void GetProcessInstanceCreateUserName(WfActivityInstanceTasksEx item, Guid userId)
        {

            WfProcessInstance processInstance = DBHelper.WfProcessInstance.FirstOrDefault(t => t.AppInstanceID == item.AppInstanceID && t.ProcessGUID == item.ProcessGUID);
            var logscount = DBHelper.FormCirculatedDocumentLog.Where(t => t.AppInstanceID == item.AppInstanceID && t.CreateUserID == userId && t.Status == 2).ToList();
            item.AppInstanceCreateTime = processInstance.CreatedDateTime;
            if (processInstance != null)
            {
                item.AppInstanceCreateUserName = processInstance.CreatedByUserName;
            }
            else
            {
                item.AppInstanceCreateUserName = "";
            }
            if (logscount.Count() > 0 && logscount.First().CreateUserID == userId)
            {
                FormCirculatedDocumentLog log = logscount.First();
                if (log.CheckType == 1)
                {
                    item.IsReplay = 1;
                }
                else
                {
                    item.IsReplay = 2;
                }
            }
        }
        public IList<WfProcessInstanceEx> GetAllProccessInstance(short state, int skip, int take, out int total, string ky = "", long typeID = 0, string dtStart = "", string dtEnd = "",
           string kewyword = "", string UserIDs = "", string DeparmentID = "", string ProcessGuid = "")
        {
            var efemployeeInfoProvider = FB.Providers.AspNetEmployeeInfoProviderManager.Default as FB.Providers.EFEmployeeInfoProvider;
            FB.Providers.EmployeeInfo.EmployeeInfoUnit unitinfo = efemployeeInfoProvider.GetEmployeeInfoUnit();
            var transtion = WfActivityInstanceTasksRepository.GetActivityInstanceTasks();
            var query = from item in DBHelper.WfProcessInstance
                        join trans in transtion on item.AppInstanceID equals trans.AppInstanceID
                        select item;
            if (state > 0)
            {
                query = query.Where(t => t.ProcessState == state);
            }

            if (typeID > 0)
            {
                query = from item in query
                        join process in DBHelper.WfProcess on item.ProcessGUID equals process.ProcessGUID
                        where process.WfProcessTypeID == typeID
                        select item;
            }
            if (!string.IsNullOrEmpty(dtStart) && !string.IsNullOrEmpty(dtEnd))
            {
                DateTime dtStartTime = DateTime.Parse(dtStart);
                DateTime dtEndTime = DateTime.Parse(dtEnd);
                query = query.Where(t => t.CreatedDateTime >= dtStartTime && t.CreatedDateTime <= dtEndTime);
            }
            if (!string.IsNullOrEmpty(ProcessGuid))
            {
                query = query.Where(t => t.ProcessGUID == new Guid(ProcessGuid));
            }

            if (!string.IsNullOrEmpty(DeparmentID))
            {
                IList<vw_Employees> employee = Regularrespository.GetEmployeeByDeparment(DeparmentID);
                foreach (var i in employee)
                {
                    UserIDs = UserIDs + ";" + i.UserID.ToString();
                }
            }
            if (!string.IsNullOrEmpty(UserIDs))
            {
                List<Guid?> UserIDList = new List<Guid?>();
                string[] strUserID = UserIDs.Split(";".ToArray());
                foreach (string item in strUserID)
                {
                    if (!string.IsNullOrEmpty(item))
                    {
                        UserIDList.Add(new Guid(item));
                    }
                }
                query = query.Where(t => UserIDList.Contains(t.CreatedByUserID));
            }
            if (!string.IsNullOrEmpty(kewyword))
            {
                long instanceID = 0;
                long.TryParse(kewyword, out instanceID);
                if (instanceID == 0)
                {
                    query = query.Where(t => t.AppName.IndexOf(kewyword) > -1);
                }
                else
                {
                    query = query.Where(t => t.AppInstanceID == instanceID);
                }
            }
            total = query.Distinct().Count();
            IList<WfProcessInstance> WfProcessInstanceList = query.Distinct().OrderByDescending(t => t.CreatedDateTime).Skip(skip).Take(take).ToList();
            IList<WfProcessInstanceEx> WfProcessInstanceExList = new List<WfProcessInstanceEx>();
            foreach (WfProcessInstance item in WfProcessInstanceList)
            {
                WfProcessInstanceEx model = new WfProcessInstanceEx()
                {
                    RowVersionID = item.RowVersionID,
                    AppInstanceCode = item.AppInstanceCode,
                    AppInstanceID = item.AppInstanceID,
                    AppName = item.AppName,
                    CreatedByUserID = item.CreatedByUserID,
                    CreatedDateTime = item.CreatedDateTime,
                    EndedByUserID = item.EndedByUserID,
                    EndedByUserName = item.EndedByUserName,
                    ID = item.ID,
                    CreatedByUserName = item.CreatedByUserName,
                    EndedDateTime = item.EndedDateTime,
                    IsProcessCompleted = item.IsProcessCompleted,
                    LastUpdatedByUserID = item.LastUpdatedByUserID,
                    LastUpdatedByUserName = item.LastUpdatedByUserName,
                    LastUpdatedDateTime = item.LastUpdatedDateTime,
                    ProcessGUID = item.ProcessGUID,
                    ProcessName = item.ProcessName,
                    ProcessState = item.ProcessState,
                    RecordStatusInvalid = item.RecordStatusInvalid,
                };
                WfActivityInstanceTasksEx taskEx = transtion.Where(t => t.AppInstanceID == model.AppInstanceID).OrderByDescending(t => t.CreatedDateTime).First();
                model.ActivityName = taskEx.ActivityName;
                model.SendUserName = taskEx.CreatedByUserName;
                WfProcessInstanceExList.Add(model);
            }

            return WfProcessInstanceExList;
        }


        public IList<WfProcessInstanceEx> GetDepartmentProcessInstance(short state, int skip, int take, out int total, string ky = "", long typeID = 0, string dtStart = "", string dtEnd = "",
          string kewyword = "", IList<Guid?> UserIDs = null, string ProcessGuid = "")
        {
            var efemployeeInfoProvider = FB.Providers.AspNetEmployeeInfoProviderManager.Default as FB.Providers.EFEmployeeInfoProvider;
            FB.Providers.EmployeeInfo.EmployeeInfoUnit unitinfo = efemployeeInfoProvider.GetEmployeeInfoUnit();
            var transtion = WfActivityInstanceTasksRepository.GetActivityInstanceTasks();
            var query = from item in DBHelper.WfProcessInstance
                        join trans in transtion on item.AppInstanceID equals trans.AppInstanceID
                        select item;
            if (state > 0)
            {
                query = query.Where(t => t.ProcessState == state);
            }
            if (typeID > 0)
            {
                query = from item in query
                        join process in DBHelper.WfProcess on item.ProcessGUID equals process.ProcessGUID
                        where process.WfProcessTypeID == typeID
                        select item;
            }
            if (!string.IsNullOrEmpty(dtStart) && !string.IsNullOrEmpty(dtEnd))
            {
                DateTime dtStartTime = DateTime.Parse(dtStart);
                DateTime dtEndTime = DateTime.Parse(dtEnd);
                query = query.Where(t => t.CreatedDateTime >= dtStartTime && t.CreatedDateTime <= dtEndTime);
            }
            if (UserIDs != null)
            {

                query = query.Where(t => UserIDs.Contains(t.CreatedByUserID));
            }
            if (!string.IsNullOrEmpty(ProcessGuid))
            {
                query = query.Where(t => t.ProcessGUID == new Guid(ProcessGuid));
            }
            if (!string.IsNullOrEmpty(kewyword))
            {
                long instanceID = 0;
                long.TryParse(kewyword, out instanceID);
                if (instanceID == 0)
                {
                    query = query.Where(t => t.AppName.IndexOf(kewyword) > -1);
                }
                else
                {
                    query = query.Where(t => t.AppInstanceID == instanceID);
                }
            }
            total = query.Distinct().Count();
            IList<WfProcessInstance> WfProcessInstanceList = query.Distinct().OrderByDescending(t => t.CreatedDateTime).Skip(skip).Take(take).ToList();
            IList<WfProcessInstanceEx> WfProcessInstanceExList = new List<WfProcessInstanceEx>();
            foreach (WfProcessInstance item in WfProcessInstanceList)
            {
                WfProcessInstanceEx model = new WfProcessInstanceEx()
                {
                    RowVersionID = item.RowVersionID,
                    AppInstanceCode = item.AppInstanceCode,
                    AppInstanceID = item.AppInstanceID,
                    AppName = item.AppName,
                    CreatedByUserID = item.CreatedByUserID,
                    CreatedDateTime = item.CreatedDateTime,
                    EndedByUserID = item.EndedByUserID,
                    EndedByUserName = item.EndedByUserName,
                    ID = item.ID,
                    CreatedByUserName = item.CreatedByUserName,
                    EndedDateTime = item.EndedDateTime,
                    IsProcessCompleted = item.IsProcessCompleted,
                    LastUpdatedByUserID = item.LastUpdatedByUserID,
                    LastUpdatedByUserName = item.LastUpdatedByUserName,
                    LastUpdatedDateTime = item.LastUpdatedDateTime,
                    ProcessGUID = item.ProcessGUID,
                    ProcessName = item.ProcessName,
                    ProcessState = item.ProcessState,
                    RecordStatusInvalid = item.RecordStatusInvalid,
                };
                WfActivityInstanceTasksEx taskEx = transtion.Where(t => t.AppInstanceID == model.AppInstanceID).OrderByDescending(t => t.CreatedDateTime).First();
                model.ActivityName = taskEx.ActivityName;
                model.SendUserName = taskEx.CreatedByUserName;
                WfProcessInstanceExList.Add(model);
            }

            return WfProcessInstanceExList;
        }

        #endregion



        public IList<WfProcessInstanceEx> GetFCDBlProccessInstance(Guid userId, short state, int skip, int take, out int total, string ky = "", long typeID = 0, string dtStart = "", string dtEnd = "",
        string kewyword = "", string UserIDs = "", string DeparmentID = "", string ProcessGuid = "")
        {
            var efemployeeInfoProvider = FB.Providers.AspNetEmployeeInfoProviderManager.Default as FB.Providers.EFEmployeeInfoProvider;
            FB.Providers.EmployeeInfo.EmployeeInfoUnit unitinfo = efemployeeInfoProvider.GetEmployeeInfoUnit();
            var transtion = WfActivityInstanceTasksRepository.GetActivityInstanceTasks();
            var query = (from item in DBHelper.WfProcessInstance
                         join log in DBHelper.FormCirculatedDocumentLog on item.AppInstanceID equals log.AppInstanceID into docLog
                         from FormDocLog in docLog.DefaultIfEmpty()
                         join trans in transtion on item.AppInstanceID equals trans.AppInstanceID
                         where item.CreatedByUserID == userId || trans.CreatedByUserID == userId || trans.AssignedToUserID == userId
                         || item.EndedByUserID == userId || item.LastUpdatedByUserID == userId || trans.EndedByUserID == userId
                         || FormDocLog.UserID == userId
                         select new WfProcessInstanceEx()
                         {
                             AppInstanceCode = item.AppInstanceCode,
                             AppInstanceID = item.AppInstanceID,
                             AppName = item.AppName,
                             CreatedByUserID = item.CreatedByUserID,
                             CreatedByUserName = item.CreatedByUserName,
                             CreatedDateTime = item.CreatedDateTime,
                             EndedByUserID = item.EndedByUserID,
                             EndedByUserName = item.EndedByUserName,
                             EndedDateTime = item.EndedDateTime,
                             ID = item.ID,
                             IsProcessCompleted = item.IsProcessCompleted,
                             LastUpdatedByUserID = item.LastUpdatedByUserID,
                             LastUpdatedByUserName = item.LastUpdatedByUserName,
                             LastUpdatedDateTime = item.LastUpdatedDateTime,
                             ProcessGUID = item.ProcessGUID,
                             RecordStatusInvalid = item.RecordStatusInvalid,
                             ProcessState = item.ProcessState,
                             ProcessName = item.ProcessName,
                             RowVersionID = item.RowVersionID,
                             CheckType = FormDocLog != null ? FormDocLog.CheckType.Value + 1 : 1,

                         }).Distinct();
            query = query.Where(t => t.ProcessGUID == new Guid("0e37f0c1-737b-4653-93dd-d01a3fbc28f7"));
            if (state > 0)
            {
                query = query.Where(t => t.ProcessState == state);
            }

            if (typeID > 0)
            {
                query = from item in query
                        join process in DBHelper.WfProcess on item.ProcessGUID equals process.ProcessGUID
                        where process.WfProcessTypeID == typeID
                        select item;
            }
            if (!string.IsNullOrEmpty(dtStart) && !string.IsNullOrEmpty(dtEnd))
            {
                DateTime dtStartTime = DateTime.Parse(dtStart);
                DateTime dtEndTime = DateTime.Parse(dtEnd);
                query = query.Where(t => t.CreatedDateTime >= dtStartTime && t.CreatedDateTime <= dtEndTime);
            }
            if (!string.IsNullOrEmpty(DeparmentID))
            {
                IList<vw_Employees> employee = Regularrespository.GetEmployeeByDeparment(DeparmentID);
                foreach (var i in employee)
                {
                    UserIDs = UserIDs + ";" + i.UserID.ToString();
                }
            }
            if (!string.IsNullOrEmpty(ProcessGuid))
            {
                query = query.Where(t => t.ProcessGUID == new Guid(ProcessGuid));
            }
            if (!string.IsNullOrEmpty(UserIDs))
            {
                List<Guid?> UserIDList = new List<Guid?>();
                string[] strUserID = UserIDs.Split(";".ToArray());
                foreach (string item in strUserID)
                {
                    if (!string.IsNullOrEmpty(item))
                    {
                        UserIDList.Add(new Guid(item));
                    }
                }
                query = query.Where(t => UserIDList.Contains(t.CreatedByUserID));
            }

            if (!string.IsNullOrEmpty(kewyword))
            {
                long instanceID = 0;
                long.TryParse(kewyword, out instanceID);
                if (instanceID == 0)
                {
                    query = query.Where(t => t.AppName.IndexOf(kewyword) > -1);
                }
                else
                {
                    query = query.Where(t => t.AppInstanceID == instanceID);
                }

            }
            if (!string.IsNullOrEmpty(ky))
            {
                long instanceID = 0;
                long.TryParse(ky, out instanceID);
                if (instanceID == 0)
                {
                    query = query.Where(t => t.AppName.IndexOf(ky) > -1);
                }
                else
                {
                    query = query.Where(t => t.AppInstanceID == instanceID);
                }

            }
            total = query.Count();
            IList<WfProcessInstanceEx> WfProcessInstanceList = query.OrderByDescending(t => t.LastUpdatedDateTime).Skip(skip).Take(take).ToList();

            foreach (WfProcessInstanceEx item in WfProcessInstanceList)
            {
                if (item.CheckType == 2)
                {
                    item.AppName = "传阅：" + item.AppName;
                }
                if (item.CheckType == 3)
                {
                    item.AppName = "征求意见：" + item.AppName;
                }
                IList<WfActivityInstanceTasksEx> list = transtion.Where(t => t.AppInstanceID == item.AppInstanceID).OrderByDescending(t => t.CreatedDateTime).ToList();

                WfActivityInstanceTasksEx taskEx = list.First();
                item.ActivityName = taskEx.ActivityName;
                item.SendUserName = taskEx.CreatedByUserName;
                if (item.ProcessState == 2)
                {
                    item.ReceiveUserName = "";
                    StringBuilder strBuilder = new StringBuilder();
                    list = list.Where(t => t.TaskState < 4 && (t.ActivityState == 1 || t.ActivityState == 2)).ToList();
                    foreach (var taskItemEx in list)
                    {
                        strBuilder.Append(taskItemEx.AssignedToUserName + ",");
                    }
                    if (strBuilder.Length > 0)
                    {
                        item.ReceiveUserName = strBuilder.ToString(0, strBuilder.Length - 1);
                    }
                }
            }

            return WfProcessInstanceList;
        }
    }
}
